package com.licheedev.serialtool.activity;

import android.os.Bundle;
import android.serialport.SerialPortFinder;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import butterknife.BindView;
import butterknife.OnClick;


import com.licheedev.serialtool.R;
import com.licheedev.serialtool.activity.base.BaseActivity;
import com.licheedev.serialtool.comn.Device;
import com.licheedev.serialtool.comn.SerialPortManager;
import com.licheedev.serialtool.util.ByteUtil;
import com.licheedev.serialtool.util.Constant;
import com.licheedev.serialtool.util.PrefHelper;
import com.licheedev.serialtool.util.ToastUtil;
import com.licheedev.serialtool.util.constant.PreferenceKeys;

import java.util.ArrayList;
import java.util.Arrays;

import static com.licheedev.serialtool.R.array.baudrates;

public class MainActivity extends BaseActivity implements AdapterView.OnItemSelectedListener {

    @BindView(R.id.spinner_devices)
    Spinner mSpinnerDevices;
    @BindView(R.id.spinner_baudrate)
    Spinner mSpinnerBaudrate;
    @BindView(R.id.btn_open_device)
    Button mBtnOpenDevice;
    @BindView(R.id.btn_send_data)
    Button btn_send_data;
    @BindView(R.id.btn_send_hex)
    Button btn_send_hex;
    @BindView(R.id.send_500)
    Button send_500;
    @BindView(R.id.send_1000)
    Button send_1000;
    @BindView(R.id.send_2000)
    Button send_2000;
    @BindView(R.id.stop_send)
    Button stop_send;
    @BindView(R.id.btn_load_list)
    Button mBtnLoadList;
    @BindView(R.id.et_data)
    EditText mEtData;

    @BindView(R.id.at_csq)
    Button at_csq;

    @BindView(R.id.at_cimi)
    Button at_cimi;

    @BindView(R.id.at_iccid)
    Button AT_ICCID;

    @BindView(R.id.at_zpas)
    Button AT_ZPAS;

    @BindView(R.id.at_cifsr)
    Button at_cifsr;

    @BindView(R.id.at_cstt)
    Button AT_ZCELLINFO;

    @BindView(R.id.at_ciicr)
    Button AT_ZSNT_6;

    @BindView(R.id.AT_CIPPING)
    Button AT_ZSNT_7;

    @BindView(R.id.AT_ZSNT_8)
    Button AT_ZSNT_8;

    @BindView(R.id.at_zrst)
    Button AT_ZRST;

    @BindView(R.id.at_cfun_0)
    Button AT_CFUN_0;

    @BindView(R.id.at_cfun_1)
    Button AT_CFUN_1;

    @BindView(R.id.AT_ZECMCALL)
    Button AT_ZECMCALL;

    @BindView(R.id.at_zlockcell_query)
    Button AT_ZLOCKCELL_QUERY;

    @BindView(R.id.at_zlockcell_unlock)
    Button AT_ZLOCKCELL_UNLOCK;

    @BindView(R.id.AT_CPIN)
    Button AT_CPIN;

    @BindView(R.id.AT_ZLOCKCELL)
    Button AT_ZLOCKCELL;

    @BindView(R.id.sim_0)
    Button sim_0;

    @BindView(R.id.sim_1)
    Button sim_1;

    @BindView(R.id.sim_2)
    Button sim_2;

    @BindView(R.id.sim_3)
    Button sim_3;

    @BindView(R.id.AT_CGSN)
    Button AT_CGSN;

    @BindView(R.id.AT_ZLOCKCELL_ARFCN)
    EditText AT_ZLOCKCELL_ARFCN;

    @BindView(R.id.AT_ZLOCKCELL_PCI)
    EditText AT_ZLOCKCELL_PCI;

    @BindView(R.id.AT_ZLOCKCELL_BAND)
    EditText AT_ZLOCKCELL_BAND;
    
    
    

    private Device mDevice;

    private int mDeviceIndex;
    private int mBaudrateIndex;

    private String[] mDevices;
    private String[] mBaudrates;

    private boolean mOpened = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

//        mEtData.setTransformationMethod(new AllCapTransformationMethod(true));

        initDevice();
        initSpinners();
        updateViewState(mOpened);
    }

    @Override
    protected void onDestroy() {
        SerialPortManager.instance().close();
        super.onDestroy();
    }

    @Override
    protected boolean hasActionBar() {
        return false;
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

    /**
     * 初始化设备列表
     */
    private void initDevice() {

        SerialPortFinder serialPortFinder = new SerialPortFinder();
        // 设备
        mDevices = serialPortFinder.getAllDevicesPath();
        if (mDevices.length == 0) {
            mDevices = new String[] {
                getString(R.string.no_serial_device)
            };
        }
        // 波特率
        mBaudrates = getResources().getStringArray(baudrates);


        mDeviceIndex = PrefHelper.getDefault().getInt(PreferenceKeys.SERIAL_PORT_DEVICES, 0);
        mDeviceIndex = mDeviceIndex >= mDevices.length ? mDevices.length - 1 : mDeviceIndex;
        mBaudrateIndex = PrefHelper.getDefault().getInt(PreferenceKeys.BAUD_RATE, 0);


        mDevice = new Device(mDevices[mDeviceIndex], mBaudrates[mBaudrateIndex]);

    }

    /**
     * 初始化下拉选项
     */
    private void initSpinners() {

        ArrayAdapter<String> deviceAdapter =
            new ArrayAdapter<String>(this, R.layout.spinner_default_item, mDevices);
        deviceAdapter.setDropDownViewResource(R.layout.spinner_item);
        mSpinnerDevices.setAdapter(deviceAdapter);
        mSpinnerDevices.setOnItemSelectedListener(this);

        ArrayAdapter<String> baudrateAdapter =
            new ArrayAdapter<String>(this, R.layout.spinner_default_item, mBaudrates);
        baudrateAdapter.setDropDownViewResource(R.layout.spinner_item);
        mSpinnerBaudrate.setAdapter(baudrateAdapter);
        mSpinnerBaudrate.setOnItemSelectedListener(this);

        mSpinnerDevices.setSelection(mDeviceIndex);
        mSpinnerBaudrate.setSelection(mBaudrateIndex);
    }

    static boolean  runActivity = false;
    @OnClick({ R.id.btn_open_device, R.id.btn_send_data,R.id.btn_send_hex, R.id.btn_load_list,
            R.id.at_csq,
            R.id.at_zpas,
            R.id.at_cimi,
            R.id.at_iccid,
            R.id.at_cstt,
            R.id.at_cifsr,
            R.id.at_cfun_0,
            R.id.at_cfun_1,
            R.id.at_zlockcell_query,
            R.id.at_zlockcell_unlock,
            R.id.AT_CPIN,
            R.id.at_zrst,
            R.id.at_ciicr,
            R.id.AT_CIPPING,
            R.id.AT_ZSNT_8,
            R.id.AT_ZECMCALL,
            R.id.AT_ZLOCKCELL,
            R.id.send_500,
            R.id.send_1000,
            R.id.send_2000,
            R.id.stop_send,
            R.id.sim_0,
            R.id.sim_1,
            R.id.sim_2,
            R.id.sim_3,
            R.id.AT_CGSN

    })
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_open_device:
                switchSerialPort();
                break;
            case R.id.btn_send_data:{
                sendData(false);
                break;
            }
            case R.id.btn_send_hex:{
                sendData(false,true);
                break;
            }

            case R.id.send_500:{
                runActivity = true;
                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        while (runActivity){
                            try {
                                sendDataCycle();
                                Thread.sleep(500);

                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }


                    }
                }).start();
                break;
            }

            case R.id.send_1000:{
                runActivity = true;
                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        while (runActivity){
                            try {
                                sendDataCycle();
                                Thread.sleep(1000);

                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }


                    }
                }).start();
                break;
            }
            case R.id.send_2000:{
                runActivity = true;
                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        while (runActivity){
                            try {
                                sendDataCycle();
                                Thread.sleep(5000);

                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }


                    }
                }).start();
                break;

            }
            case R.id.stop_send:{
                runActivity = false;
                break;

            }
            case R.id.AT_CPIN:
                sendData("AT+CPIN?");
                break;
            case R.id.at_csq:{


                sendMcuData("03");
                break;
            }

            case R.id.at_cimi:
                sendData("stdz,2,1");
//                sendData("AT+CIMI");
                break;
            case R.id.at_iccid:
                sendData("AT+ICCID");
                break;
            case R.id.at_zpas:
                sendMcuData("00");
//                sendData("AT+ZPAS?");
                break;
            case R.id.at_cifsr:
                sendData("AT+CIFSR");
                break;
            case R.id.at_cstt:
//                Log.d("__0d0a",Arrays.toString("\r\n".getBytes()));
////                sendData("AT+ZCELLINFO?");
//
//                byte[] bt = {11,12,14,115, 116, 100, 122, 44, 0, 44, 3, 44, 24, 44, 19, 44, 0, 44, 0, 13, 10,1,2,3,4,5};
//                byte[] btHeard = {115, 116, 100, 122};
//                byte[] btEnd = {13, 10};
//
//                int heard = ByteUtil.getByteIndex(bt,btHeard);
//                int end = ByteUtil.getByteIndex(bt,btEnd)+2;
//
//                Log.d("__byteIndex-heard",""+heard);
//                Log.d("__byteIndex-end",""+end);
//
//                Log.d("__byteIndex-sub-0",Arrays.toString(ByteUtil.subBytes(bt,0,heard)));
//                Log.d("__byteIndex-sub-1",Arrays.toString(ByteUtil.subBytes(bt,heard,(end-heard))));
//                Log.d("__byteIndex-sub-2",Arrays.toString(ByteUtil.subBytes(bt,end,(bt.length-end))));
                sendData("AT+CSTT");
                break;
            case R.id.at_ciicr:
                sendData("AT+CIICR");
                break;
            case R.id.AT_CIPPING:
                sendData("AT+CIPPING=\"61.177.139.106\"");
//                sendData("AT+CIPPING=\"www.baidu.com\"");
                break;
            case R.id.AT_ZSNT_8:
                sendData("AT+ZSNT=8,0,0");
                break;
            case R.id.at_zrst:
                sendData("AT+ZRST");
                break;
            case R.id.at_cfun_0:
                sendData("AT+CFUN=0");
                break;
            case R.id.at_cfun_1:
                sendData("AT+CFUN=1");
                break;
            case R.id.AT_ZECMCALL:
                sendData("AT+ZECMCALL=1");
                break;
            case R.id.at_zlockcell_query:
                sendData("AT+ZLOCKCELL?");

                break;
            case R.id.at_zlockcell_unlock:
                sendData(Constant.AT_ZLOCKCELL_UNLOCK);
                break;
            case R.id.sim_0:
                sendMcuData("00");
//                sendData("stdz,2,0,1");
                break;
            case R.id.sim_1:
                sendMcuData("01");
//                sendData("stdz,2,0,1");
                break;
            case R.id.sim_2:
                sendMcuData("02");
//                sendData("stdz,2,0,2");
                break;
            case R.id.sim_3:
                sendMcuData("03");
//                sendData("stdz,2,0,3");
                break;
            case R.id.AT_CGSN:
                sendData(Constant.AT_CGSN);
                break;
            case R.id.AT_ZLOCKCELL:{
                String arfcn = AT_ZLOCKCELL_ARFCN.getText().toString();
                String pci = AT_ZLOCKCELL_PCI.getText().toString();
                String band = AT_ZLOCKCELL_BAND.getText().toString();
                if (TextUtils.isEmpty(arfcn) || TextUtils.isEmpty(pci) ||TextUtils.isEmpty(band)){
                    ToastUtil.show(view.getContext(),"arfcn 或 pci为空");
                    return;
                }

                String command = Constant.AT_ZLOCKCELL + arfcn + "," + pci + ",1,"+band;

                Log.d("__command",command);
                sendData(command);
                break;

            }


        }
    }

    private void sendMcuData(String simFlag) {
        byte[] b1 = ByteUtil.hexStr2bytes(strTo16("stdz,"));
        byte[] b2 = ByteUtil.hexStr2bytes("00"); //心跳
        byte[] b3 = ByteUtil.hexStr2bytes(strTo16(","));
        byte[] b4 = ByteUtil.hexStr2bytes(Integer.toHexString(58)); //CPU温度
        byte[] b5 = ByteUtil.hexStr2bytes(strTo16(","));
        byte[] b6 = ByteUtil.hexStr2bytes("09"); //手机主板电池电量
        byte[] b7 = ByteUtil.hexStr2bytes(strTo16(","));
        byte[] b8 = ByteUtil.hexStr2bytes(Integer.toHexString(29)); //电池温度
        byte[] b9 = ByteUtil.hexStr2bytes(strTo16(","));
        byte[] b10 = ByteUtil.hexStr2bytes(simFlag); //SIM配置
        byte[] b11 = ByteUtil.hexStr2bytes(strTo16(","));
        byte[] b12 = ByteUtil.hexStr2bytes("0d0a");

        Log.d("__byte-0",""+Integer.toHexString(2));
        Log.d("__bytes-1",
                "b1 = "+ Arrays.toString(b1) + "\n"+
                "b2 = "+ Arrays.toString(b2) + "\n"+
                "b3 = "+ Arrays.toString(b3) + "\n"+
                "b4 = "+ Arrays.toString(b4) + "\n"+
                "b5 = "+ Arrays.toString(b5) + "\n"+
                "b6 = "+ Arrays.toString(b6) + "\n"+
                "b7 = "+ Arrays.toString(b7) + "\n");

        ArrayList<byte[]> byteArr = new ArrayList<>();
        byteArr.add(b1 );
        byteArr.add(b2 );
        byteArr.add(b3 );
        byteArr.add(b4 );
        byteArr.add(b5 );
        byteArr.add(b6 );
        byteArr.add(b7 );
        byteArr.add(b8 );
        byteArr.add(b9 );
        byteArr.add(b10);
        byteArr.add(b11);
        byteArr.add(b12);
        byte[] totalByte = addBytes(byteArr);
        String s = new String(totalByte);
        Log.d("__bytes-2","totalByte = "+Arrays.toString(totalByte)+" s = "+s);
        sendData(totalByte,true);
    }

    private void sendDataCycle() {

        String text = mEtData.getText().toString().trim();

        if (TextUtils.isEmpty(text)){

            //"stdz,0x00,"
            text = Constant.MCU_HEART;
//            byte[] byte1 = "stdz,".getBytes();
//            byte[] byte2 = ByteUtil.hexStr2bytes("0x00");
//            byte[] byte3 = ",".getBytes();
//
//            byte[] byte4 = addBytes(byte1,byte2,byte3);
            SerialPortManager.instance().sendCommand(text,false);
            return;
        }

        Log.d("__text",text);

        SerialPortManager.instance().sendCommand(text,false);
    }

    public String strTo16(String str) {

        StringBuilder newStr = new StringBuilder();
        if (TextUtils.isEmpty(str)){
            return null;
        }
        for (int i = 0; i < str.length(); i++) {
            int ch = (int) str.charAt(i);
            String s4 = Integer.toHexString(ch);
            newStr.append(s4);
        }

        return newStr.toString();
    }

    private static String intToHex(int n) {
        StringBuffer s = new StringBuffer();
        String a;
        char []b = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        while(n != 0){
            s = s.append(b[n%16]);
            n = n/16;
        }
        a = s.reverse().toString();
        return a;
    }


    private void sendData(boolean needAT,boolean...isHex) {
        boolean getIsHex = false;


        String text = mEtData.getText().toString().trim();


        if (TextUtils.isEmpty(text)) {
            ToastUtil.showOne(this, "发送内容为空");
            return;
        }


        if (needAT){
            text = "AT+"+text;
        }


        if (isHex.length > 0 && isHex[0]){
            getIsHex = true;
            text = strTo16(text);
        }

        Log.d("__text",text);

        SerialPortManager.instance().sendCommand(text,getIsHex);
    }

    private void sendData(byte[] totalByte,boolean...isHex) {
        boolean getIsHex = false;


        SerialPortManager.instance().sendCommand(totalByte,getIsHex);
    }

    public static byte[] addBytes(ArrayList<byte[]> byteArr) {

        Log.d("__byteArr-1",""+byteArr.size());

        int byteTotalLength = 0;
        int byteCurrentLength = 0;
        for (int i = 0; i < byteArr.size(); i++) {
            byteTotalLength = byteTotalLength + byteArr.get(i).length;
        }
        Log.d("__byteArr-2",""+byteTotalLength);
        byte[] newDatas = new byte[byteTotalLength];

        for (int i = 0; i<byteArr.size(); i++){
            System.arraycopy(byteArr.get(i),0,newDatas,byteCurrentLength,byteArr.get(i).length);
            byteCurrentLength = byteCurrentLength + byteArr.get(i).length;
        }
        return newDatas;


//        System.arraycopy(data1, 0, newDatas, 0, data1.length);
//        System.arraycopy(data2, 0, newDatas, data1.length, data2.length);
//        System.arraycopy(data3, 0, newDatas, data1.length + data2.length, data3.length);
//        System.arraycopy(data4, 0, newDatas, data1.length + data2.length + data3.length, data4.length);
//        System.arraycopy(data5, 0, newDatas, data1.length + data2.length + data3.length + data4.length, data5.length);
//        System.arraycopy(data6, 0, newDatas, data1.length + data2.length + data3.length + data4.length + data5.length, data6.length);
//        System.arraycopy(data7, 0, newDatas, data1.length + data2.length + data3.length + data4.length + data5.length + data6.length, data7.length);
//        System.arraycopy(data8, 0, newDatas, data1.length + data2.length + data3.length + data4.length + data5.length + data6.length + data7.length, data8.length);
//        System.arraycopy(data9, 0, newDatas, data1.length + data2.length + data3.length + data4.length + data5.length + data6.length + data7.length + data8.length, data9.length);
//        System.arraycopy(data10, 0, newDatas, data1.length + data2.length + data3.length + data4.length + data5.length + data6.length + data7.length + data8.length + data9.length, data10.length);
//        System.arraycopy(data11, 0, newDatas, data1.length + data2.length + data3.length + data4.length + data5.length + data6.length + data7.length + data8.length + data9.length + data10.length, data11.length);
//        System.arraycopy(data12, 0, newDatas, data1.length + data2.length + data3.length + data4.length + data5.length + data6.length + data7.length + data8.length + data9.length + data10.length + data11.length, data12.length);



    }

    private void sendData(String str) {

        if (TextUtils.isEmpty(str)) {
            ToastUtil.showOne(this, "发送内容为空");
            return;
        }


        Log.d("__text",str);

        SerialPortManager.instance().sendCommand(str,false);
    }

    /**
     * 打开或关闭串口
     */
    private void switchSerialPort() {
        if (mOpened) {
            SerialPortManager.instance().close();
            mOpened = false;
        } else {

            // 保存配置
            PrefHelper.getDefault().saveInt(PreferenceKeys.SERIAL_PORT_DEVICES, mDeviceIndex);
            PrefHelper.getDefault().saveInt(PreferenceKeys.BAUD_RATE, mBaudrateIndex);

            mOpened = SerialPortManager.instance().open(mDevice) != null;
            if (mOpened) {
                ToastUtil.showOne(this, "成功打开串口");
            } else {
                ToastUtil.showOne(this, "打开串口失败");
            }
        }
        updateViewState(mOpened);
    }

    /**
     * 更新视图状态
     *
     * @param isSerialPortOpened
     */
    private void updateViewState(boolean isSerialPortOpened) {

        int stringRes = isSerialPortOpened ? R.string.close_serial_port : R.string.open_serial_port;

        mBtnOpenDevice.setText(stringRes);

        mSpinnerDevices.setEnabled(!isSerialPortOpened);
        mSpinnerBaudrate.setEnabled(!isSerialPortOpened);
        btn_send_data.setEnabled(isSerialPortOpened);
        btn_send_hex.setEnabled(isSerialPortOpened);
        send_500.setEnabled(isSerialPortOpened);
        send_1000.setEnabled(isSerialPortOpened);
        send_2000.setEnabled(isSerialPortOpened);
        stop_send.setEnabled(isSerialPortOpened);
        at_csq.setEnabled(isSerialPortOpened);
        at_cimi.setEnabled(isSerialPortOpened);
        AT_ICCID.setEnabled(isSerialPortOpened);
        AT_ZPAS.setEnabled(isSerialPortOpened);
        at_cifsr.setEnabled(isSerialPortOpened);
        AT_ZCELLINFO.setEnabled(isSerialPortOpened);
        AT_ZSNT_6.setEnabled(isSerialPortOpened);
        AT_ZSNT_7.setEnabled(isSerialPortOpened);
        AT_ZSNT_8.setEnabled(isSerialPortOpened);
        AT_ZRST.setEnabled(isSerialPortOpened);
        AT_CFUN_0.setEnabled(isSerialPortOpened);
        AT_CFUN_1.setEnabled(isSerialPortOpened);
        AT_ZECMCALL.setEnabled(isSerialPortOpened);
        AT_ZLOCKCELL_QUERY.setEnabled(isSerialPortOpened);
        AT_ZLOCKCELL_UNLOCK.setEnabled(isSerialPortOpened);
        AT_CPIN.setEnabled(isSerialPortOpened);
        AT_ZLOCKCELL.setEnabled(isSerialPortOpened);
        sim_0.setEnabled(isSerialPortOpened);
        sim_1.setEnabled(isSerialPortOpened);
        sim_2.setEnabled(isSerialPortOpened);
        sim_3.setEnabled(isSerialPortOpened);
        AT_CGSN.setEnabled(isSerialPortOpened);
        AT_ZLOCKCELL_ARFCN.setEnabled(isSerialPortOpened);
        AT_ZLOCKCELL_PCI.setEnabled(isSerialPortOpened);
        AT_ZLOCKCELL_BAND.setEnabled(isSerialPortOpened);
        mBtnLoadList.setEnabled(isSerialPortOpened);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

        // Spinner 选择监听
        switch (parent.getId()) {
            case R.id.spinner_devices:
                mDeviceIndex = position;
                mDevice.setPath(mDevices[mDeviceIndex]);
                break;
            case R.id.spinner_baudrate:
                mBaudrateIndex = position;
                mDevice.setBaudrate(mBaudrates[mBaudrateIndex]);
                break;
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
        // 空实现
    }
}
